﻿using Microsoft.Extensions.Logging;
using Simple.Tools;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;

/*********************************************************
 * 命名空间 Simple.Framework.Logger
 * 接口名称  ILoggerProvider
 * 开发人员：zdm
 * 创建时间：2023/11/28 9:49:10
 * 描述说明：
 * 更改历史：
 * 
 * *******************************************************/
namespace Simple.Framework.Logger
{
	public class ClassNameLoggerProvider : ILoggerProvider
	{
		/// <summary>
		/// 
		/// </summary>
		public LogLevel CurrentLogLevel { get { return currentLogLevel; } set { currentLogLevel = value;   } }
		/// <summary>
		/// 日志
		/// </summary>
		public eRollingInterval RollingInterval { get { return rollingInterval; } set { rollingInterval = value; } }
		public bool IsConsoleWrite { get { return isConsoleWrite; } set { isConsoleWrite = value; } }
		/// <summary>
		/// 
		/// </summary>
		public string ProfixLogFile { get { return profixLogFile; } set { profixLogFile = value; } }
		public string LogFolderPath { get { return logFolderPath; } set { logFolderPath = value; } }

		public string profixLogFile;
		
		private LogLevel currentLogLevel;
		private eRollingInterval rollingInterval;
		private  string logFolderPath; // 日志文件夹路径
		private  bool isConsoleWrite; // 日志文件夹路径

		public ClassNameLoggerProvider(string folderPath)
		{
			CurrentLogLevel = LogLevel.Trace;
			LogFolderPath = folderPath;
			ProfixLogFile = string.Empty;
			RollingInterval = eRollingInterval.Day;
			IsConsoleWrite = true;
		}

		public ILogger CreateLogger(string categoryName)
		{
			//string className = string.Empty;
			ILogger logger=null;
			if (ToolSimpleCheck.IsNullOrEmpty(categoryName))
			{
				//className = categoryName.Substring(categoryName.LastIndexOf(".") + 1); // 获取类名
				logger = new ClassNameLogger(categoryName, ToolSimpleCheck.IsNullGetEmpty(logFolderPath), ToolSimpleCheck.IsNullGetEmpty(ProfixLogFile), RollingInterval,IsConsoleWrite);
				logger.IsEnabled(CurrentLogLevel);
			}
			
			return logger;
		}
		public ILogger CreateLogger(string categoryName,Type paramType)
		{
			//var className = categoryName.Substring(categoryName.LastIndexOf(".") + 1); // 获取类名
			Type loggerType = typeof(ClassNameLogger<>).MakeGenericType(paramType);
			var logger = (ILogger)Activator.CreateInstance(loggerType, GetcategoryName(paramType), ToolSimpleCheck.IsNullGetEmpty(LogFolderPath), ToolSimpleCheck.IsNullGetEmpty(ProfixLogFile), RollingInterval, IsConsoleWrite);
			logger.IsEnabled(CurrentLogLevel);
			return logger;
		}

		public ILogger CreateLogger(Type type,string categoryName, Type paramType)
		{
			LoggerFactory loggerFactory = new LoggerFactory();
			//var logger=loggerFactory.CreateLogger(categoryName);
			ILogger logger = (ILogger)Activator.CreateInstance(type.GetGenericTypeDefinition().MakeGenericType(paramType), loggerFactory);
			logger.IsEnabled(LogLevel.Information);
			return logger;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="type"></param>
		/// <returns></returns>
		private string GetcategoryName(Type type)
		{
			List<string> Params = new List<string>();
				foreach (var item in type.GetGenericArguments())
				{
					Params.Add(item.FullName);
				}
			string definition = string.Empty;
			if (type.IsGenericType)
			{
				definition = type.GetGenericTypeDefinition().FullName;
			}
			else
			{
				definition = type.FullName;
			}
			return ForamatterGetcategoryName(definition,Params);

		}

		private string ForamatterGetcategoryName(string definition,IEnumerable <string>Params)
		{
			int cout = 0;
			if (!ToolSimpleCheck.IsNullOrEmpty(Params))
			{
				foreach (var item in Params)
				{
					cout += item.Length;
				}
			}
			StringBuilder sb = new StringBuilder();

			if (!ToolSimpleCheck.IsNullOrEmpty(definition))
			{
				cout += definition.Length;
				sb.Append(definition.Replace("`1", ""));
			}
			if (cout>40)
			{
				if (!ToolSimpleCheck.IsNullOrEmpty(definition))
				{
					if (!ToolSimpleCheck.IsNullOrEmpty(Params))
					{
						sb.Append("[");
						sb.Append( string.Join('.', Params.Select(item=> item.SprlitGetFirstChar('.'))));
						sb.Append("]");
					}
				}
			}
			else
			{
				if (!ToolSimpleCheck.IsNullOrEmpty(Params))
				{
					sb.Append("[");
					sb.Append(string.Join('.', Params.Select(item => item)));
					sb.Append("]");
				}
				
			}
			return sb.ToString();
		}

		void IDisposable.Dispose()
		{
		}
	}
}
